<?php
namespace app\apijson\query\operators;

class JsonOperator
{
    public static function apply($query, $key, $value)
    {
        // JSON 数组包含查询 field<> 或 field.subfield<>
        if (preg_match('/^([\w.]+)<>$/', $key, $m)) {
            $full = $m[1];
            if (strpos($full, '.') !== false) {
                $parts = explode('.', $full, 2);
                $field = $parts[0];
                $path = '$.' . $parts[1];
                if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $field)) {
                    throw new \app\apijson\core\ApiJsonException('非法 JSON 字段: ' . $field);
                }
                if (!preg_match('/^[a-zA-Z0-9_$.]+$/', $path)) {
                    throw new \app\apijson\core\ApiJsonException('非法 JSON 路径: ' . $path);
                }
            } else {
                $field = $full;
                $path = null;
                if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $field)) {
                    throw new \app\apijson\core\ApiJsonException('非法 JSON 字段: ' . $field);
                }
            }
            
            if (is_array($value)) {
                $query->where(function($q) use ($field, $path, $value) {
                    foreach ($value as $v) {
                        $param = json_encode($v);
                        if ($path) {
                            $q->orWhereRaw("JSON_CONTAINS($field, ?, ?)", [$param, $path]);
                        } else {
                            $q->orWhereRaw("JSON_CONTAINS($field, ?)", [$param]);
                        }
                    }
                });
            } else {
                $param = json_encode($value);
                if ($path) {
                    $query->whereRaw("JSON_CONTAINS($field, ?, ?)", [$param, $path]);
                } else {
                    $query->whereRaw("JSON_CONTAINS($field, ?)", [$param]);
                }
            }
            return true;
        }
        
        return false;
    }
} 